"""
用于sdf数据的处理的函数
主要有计算最大最，百分位数，方差
"""
import numpy as np
from ..plot import plot_parm as pp
from ..sim_parm import *


def find_percentile(Z, x, y, yx, yy, p):
    """
    二维数组Z，以第一维(x,y)第二维(yx，yy)为范围 
    注意输入的Z数组要求是转置的
    找到其中每一个p百分位数所在的数组坐标，返回基于给定范围为起始值的坐标
    """
    res_x = np.zeros(y - x)
    res_y = np.zeros(y - x)
    start = yx
    end = yy
    for i in range(x, y):
        # print('in find_percentile i=', i)
        #这里开始寻找每一个固定的x对应的指定百分位数的位置，y_axis记录找到点的y坐标
        # start = int(0.5 * (yx + yy))  # 从中心轴开始计算
        temp = Z[start:end, i]
        temp = np.abs(temp)
        temp = temp.astype(
            np.int64
        )  #这里要转化为整形，如果直接使用内置float比较，可能由于有效位数的关系，基本找不到可以匹配的值。(或者是percentile函数会进行插值,默认线性插值)
        temp2 = int(np.percentile(temp, p, interpolation='nearest'))
        #下面循环体可以用np.where函数代替
        k = 0
        for k in range(end - start):
            if (temp[k] == temp2):
                break
        # print('test whether have found the percentile point ')
        # print('temp2:', temp2, 'type of temp2:', (type(temp2)),
        #       '\n found point---position k& temp[k]:', k, temp[k])
        # print(temp)
        res_x[i - x] = i
        res_y[i - x] = k + start

    # print('res_x=========================================================')
    # print('res_x', res_x)
    # print('res_y=========================================================')
    # print('res_y', res_y)
    # print('end of find_percentile========================================')
    return (res_x, res_y)


def find_nearest_value(Z, x, y, yx, yy, value, error=0.01, confirm=0):
    """
    找到在每个x截面上，离给定value值最近的点，
    注意Z是转置的
    最近值的要求是|值-value|<error,默认为0.01
    confirm值是为了，防止出现数值误差，默认为0。当error为0时，寻找第一个出现的符合条件的值，其余情况下，返回值应满足其与邻近值的差别小于给定的百分比。
    同样，返回值基于给定范围为起始值的坐标
    """
    flag = 0
    res_x = np.zeros(0)
    res_y = np.zeros(0)
    start = yx
    end = yy
    for i in range(x, y):
        temp = Z[start:end, i]
        k = 0
        for k in range(end - start):
            if (np.abs(temp[k] - value) <= error * value):
                break
        if ((k == yy - yx - 1) & (np.abs(temp[k] - value) > error * value)):
            flag += 1
            continue
        # print('test whether have found the percentile point ')
        # print('temp2:', temp2, 'type of temp2:', (type(temp2)),
        #       '\n found point---position k& temp[k]:', k, temp[k])
        # print(temp)
        res_x = np.append(res_x, i)
        res_y = np.append(res_y, k + start)

    if (flag != 0):
        print(
            "in find_nearest_value,there is %d point which can not satisfy the requirement"
            % (flag))
        print("these points have been deleted")
    return (res_x, res_y)


def cal_coordinate(x_axis, y_axis, x_start, y_start):
    """
    返回真实的坐标位置
    x_start,y_start是的真实起始数组(全局数据数组)下标。
    坐标依赖于input.deck的各种参数，xmax,xmin,ymax,ymin,nx,ny
    """
    res_x = np.zeros(len(x_axis))
    res_y = np.zeros(len(x_axis))
    for i in range(len(x_axis)):
        # print('in cal_coordinate i=', i)
        res_x[i] = (x_axis[i] + x_start) / nx * (xmax - xmin) + xmin
        res_y[i] = (y_axis[i] + y_start) / ny * (ymax - ymin) + ymin
    # print('res_x=========================================================')
    # print('res_x', res_x)
    # print('res_y=========================================================')
    # print('res_y', res_y)
    # print('end of cal_coordinate========================================')
    return (res_x, res_y)


def data_analyse(Z, x, y, yx, yy, E_invalid=1):
    max_ey = 0
    max_ey_num = 0
    for i in range(x, y):
        # #这里开始，直接求每个x截面上的最大值
        # temp = Z[yx:yy, i]
        # x_axis[i] = i * 50e-6 / nx
        # y_axis[i] = (np.argmax(temp) - int(0.5 * ny)) * 1000e-6 / ny

        #这里开始，找每一个固定的x截面上的场强最大值以及全局的最大值(用剔除了小于自定义最低临界值的99百分位数计算)
        temp = Z[yx:yy, i].flatten()
        temp2 = len(temp)
        # print('original len:%d' % temp2)
        k = 0
        for j in range(temp2):  #该循环剔除电场强度小于某一给定值E_invalid
            if 0:  #abs(temp[k]) < E_invalid
                temp = np.delete(temp, k)
            else:
                k += 1
        # print('operated len:%d' % len(temp))
        #max_ey用来保存全局最大值
        temp_val = np.percentile(temp, 99.9)
        if max_ey < temp_val:
            max_ey = temp_val
            max_ey_num = i
    print(
        '==========here is the result of data analyse================================================='
    )
    print('max i=', i)
    print('max_ey is', max_ey, 'in x=', max_ey_num)
    #====================================================
    temp = Z[yx:yy, max_ey_num]
    print('x[max_ey_num].mean=', temp.mean())
    print('x[max_std_num].percentile.99=', temp.std())
    #====================================================
    return (max_ey_num, max_ey, temp.mean(), temp.std())
